# -*- coding: utf-8 -*-
import sys
import mongoengine
import os

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
from flask import *
from functools import wraps
from core.logger import Loger
from core.tools import dumps
from core.model import DevData, Device, User, Maprecord, Admin, SOS
from core.cache import redis
# statistic = Blueprint('statistic', __name__, static_folder='static', template_folder='templates')
app = Flask(__name__)


def request_login(fun):
    @wraps(fun)
    def check_login(*args, **kwargs):
        token = request.cookies.get('tokens')
        userid = request.cookies.get('client')
        if token and userid:
            utoken = redis.hget('Admin:' + userid, 'token')
            if token == utoken:
                return fun(*args, **kwargs)
        return render_template('login.html')

    return check_login


@app.route('/v1/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')
    try:
        user = Admin.objects(username=username, password=password).get()
    except mongoengine.DoesNotExist:
        return 'no'
    userid = str(user.id)
    token = os.urandom(24).encode('base64')
    redis.hset('Admin:' + userid, 'token', token)
    resp = make_response('ok')
    resp.set_cookie('tokens', token, max_age=43200)
    resp.set_cookie('client', userid, max_age=43200)
    return resp


@app.route('/v1/modify_password', methods=['POST'])
@request_login
def modify_password():
    password = request.form.get('password')
    new_password = request.form.get('new_password')
    user_id = request.cookies.get('client')
    try:
        user = Admin.objects(id=user_id, password=password).get()
    except mongoengine.DoesNotExist:
        return 'no'
    user.password = new_password
    user.save()
    return 'ok'


@app.route('/v1/logout', methods=['POST'])
def logout():
    if request.cookies.get('tokens'):
        resp = make_response('200')
        resp.set_cookie('tokens', '', expires=0)
        resp.set_cookie('client', '', expires=0)
        return resp
    return '200'


@app.route('/', methods=['GET'])
@request_login
def index():
    return render_template('index.html')


@app.errorhandler(404)
def nofind(e):
    return render_template('error.html', code='404', message=u'该页面不存在'), 404


@app.errorhandler(500)
def failed(e):
    return render_template('error.html', code='505', message=u'服务器未知错误'), 500


@app.route('/v1/status_record_length', methods=['GET', 'POST'])
@request_login
def status_record_length():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    count = Loger.objects(model='server', event='status', ident=imei).count()
    return str(count)


@app.route('/v1/status_record', methods=['GET', 'POST'])
@request_login
def status_record():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    page = page if page > 0 else 0
    num = num if num > 0 else 10
    data = [{'time': i.time, 'ident': i.ident, 'value': i.value} for i in Loger \
        .objects(model='server', event='status', ident=imei)
        .only('time', 'ident', 'value').order_by('-id').limit(num).skip(page * num)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/interact_record_length', methods=['GET'])
@request_login
def interact_record_length():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    count = Loger.objects(model='server', event__in=('send', 'recv'), ident=imei).count()
    return str(count)


@app.route('/v1/interact_record', methods=['GET', 'POST'])
@request_login
def interact_record():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    page = page if page > 0 else 0
    num = num if num > 0 else 10
    data = [{'time': i.time, 'ident': i.ident, 'event': i.event, 'value': i.value} \
            for i in Loger.objects(model='server', event__in=('send', 'recv'), ident=imei)
                .only('time', 'ident', 'event', 'value').order_by('-id').limit(num).skip(page * num)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/wb_data_length', methods=['GET', 'POST'])
@request_login
def wb_data_length():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    count = DevData.objects(dev=imei).count()
    return str(count)


@app.route('/v1/wb_data', methods=['GET', 'POST'])
@request_login
def wb_data():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    data = [{'step': i.step, 'distance': i.distance, 'time': i.date, 'calories': i.calories} \
            for i in DevData.objects(dev=imei).only('step', 'distance', 'date', 'calories') \
                .order_by('-date').limit(num).skip(num * page)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/wb_info_length', methods=['GET', 'POST'])
@request_login
def wb_info_length():
    count = Device.objects().count()
    return str(count)


@app.route('/v1/wb_info', methods=['GET', 'POST'])
@request_login
def wb_info():
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    data = [{'imei': i.imei, 'name': i.name, 'maketime': i.maketime, 'lasttime': i.lasttime, \
             'age': i.age, 'height': i.height, 'weight': i.weight, 'steplen': i.steplen, 'voltage': i.voltage, \
             'sex': i.sex, 'phone': i.phone} for i in Device.objects().order_by('-maketime') \
                .limit(num).skip(num * page)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/user_info_length', methods=['GET', 'POST'])
@request_login
def user_info_length():
    count = User.objects().count()
    return str(count)


@app.route('/v1/user_info', methods=['GET', 'POST'])
@request_login
def user_info():
    page = int(request.args.get('page'))
    num = int(request.args.get('num'))
    data = [{'id': i.id, 'phone': i.phone, 'email': i.email, 'password': i.password, \
             'token': i.token, 'maketime': i.maketime, 'lasttime': i.lasttime, \
             'admin': i.admin} for i in User.objects().order_by('-maketime') \
                .limit(num).skip(num * page)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/wb_location_length', methods=['GET', 'POST'])
@request_login
def wb_location_length():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    count = Maprecord.objects(dev=imei).count()
    return str(count)


@app.route('/v1/wb_location', methods=['GET', 'POST'])
@request_login
def wb_location():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    data = [{'lon': i.lon, 'lat': i.lat, 'address': i.address, 'time': i.time, \
             'radius': i.radius, 'useGPS': i.useGPS} for i in Maprecord.objects(dev=imei) \
                .order_by('-time').limit(num).skip(num * page)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response


@app.route('/v1/wb_sos_length', methods=['GET', 'POST'])
@request_login
def wb_sos_length():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    count = SOS.objects(dev=imei).count()
    return str(count)


@app.route('/v1/wb_sos', methods=['GET', 'POST'])
@request_login
def wb_sos():
    imei = request.args.get('imei')
    if not imei:
        return abort(403)
    page = int(request.args.get('page', 0))
    num = int(request.args.get('num', 10))
    data = [{'lon': i.lon, 'lat': i.lat, 'time': i.time, 'address': i.address} \
            for i in SOS.objects(dev=imei).order_by('-time').limit(num) \
                .skip(num * page)]
    response = make_response(dumps(data))
    response.headers['Content-Type'] = 'application/json'
    return response
